#define _CRT_SECURE_NO_WARNINGS	
#include "MyString.h"
#include <string>

void MyString::ensure_capacity(size_t minCapacity)
{
	if (minCapacity > _nCapacity)//扩容条件
	{
		size_t nCapacity = std::max(minCapacity, 2 * _nCapacity);
		char* strData = new char[nCapacity + 1] {};//+1用作结束符

		if (_pStrData)//内存搬移
		{
			std::memcpy(strData, _pStrData, _nSize);//直接按照长度进行拷贝
			//std::strcpy(strData, _strData);//实际上这里复制的已经复制了标识符，
			delete[] _pStrData;//释放内存
		}

		_pStrData = strData;
		_nCapacity = nCapacity;
		//_strData[_nCapacity] = '\0';//保证最后一位结尾是\0
	}
}

MyString::MyString() : _pStrData(new char[1] {}), _nSize(0), _nCapacity(0)
{

}

MyString::MyString(const char* strValue)
{
	_nSize = std::strlen(strValue);//以'\0'作为结束符、可能不为实际长度
	_nCapacity = _nSize;
	_pStrData = new char[_nCapacity + 1] {};
	std::strcpy(_pStrData, strValue);
}

MyString::MyString(const char* strValue, int nLen) 
	: _nSize(nLen), _nCapacity(nLen), _pStrData(new char[nLen + 1] {})
{
	//std::strcpy(_strData, strValue);
	std::memcpy(_pStrData, strValue, _nSize);
}

MyString::MyString(const std::string strValue)
	: MyString(strValue.c_str(),strValue.size())//委托构造
{
}

MyString::MyString(const MyString& strValue)
{
	_nCapacity = strValue._nCapacity;
	_nSize = strValue._nSize;
	_pStrData = new char[_nCapacity + 1] {};
	std::memcpy(_pStrData, strValue._pStrData, _nSize);
}

MyString::MyString(MyString&& strValue) noexcept
	: _pStrData(strValue._pStrData) , _nSize(strValue._nSize) , _nCapacity(strValue._nCapacity)
{
	strValue._nCapacity = 0;
	strValue._nSize = 0;
	strValue._pStrData = nullptr;
}

MyString& MyString::operator = (const MyString& strValue)
{
	if (this != &strValue)//防止自我赋值
	{
		MyString strTemp(strValue);
		swap(strTemp);//copy + swap 最常用的方法
	}
	return *this;
}

MyString& MyString::operator = (MyString&& strValue) noexcept
{
	if (this != &strValue)
	{
		delete[] _pStrData;//释放旧资源
		_pStrData = strValue._pStrData;
		_nSize = strValue._nSize;
		_nCapacity = strValue._nCapacity;

		strValue._pStrData = nullptr;
		strValue._nCapacity = 0;
		strValue._nSize = 0;
	}
	return *this;
}

MyString::~MyString()
{
	delete[] _pStrData;
}

void MyString::swap(MyString& strValue)
{
	if (this != &strValue)//防止自己与自己交换
	{
		std::swap(_pStrData, strValue._pStrData);
		std::swap(_nCapacity, strValue._nCapacity);
		std::swap(_nSize, strValue._nSize);
	}
}

inline size_t MyString::capacity() const
{
	return _nCapacity;
}

inline size_t MyString::size() const
{
	return _nSize;
}

inline const char* MyString::c_str() const
{
	return _pStrData;
}

void MyString::clear()
{
	_nSize = 0;
	if (_pStrData)
	{
		_pStrData[0] = '\0';
	}
}

void MyString::reserve(size_t nCapacity)
{
	if (nCapacity > _nCapacity)
	{
		char* pStrData = new char[nCapacity + 1]{};
		memcpy(pStrData, _pStrData, _nSize);

		delete[] _pStrData;
		_pStrData = pStrData;
		_nCapacity = nCapacity;
	}
}

void MyString::resize(size_t nSize , char strData)
{
	ensure_capacity(nSize);//保证capacity > size

	for (size_t i = _nSize; i < nSize; i++)
	{
		_pStrData[i] = strData;
	}

	_nSize = nSize;
	_pStrData[nSize] = '\0';//末尾加入结束终止符
}

void MyString::shrink_to_fit()
{
	if (_nCapacity > _nSize)
	{
		MyString strTemp(_pStrData, _nSize);//创一个合适尺寸的对象
		*this = std::move(strTemp);
	}
}

void MyString::append(const MyString& strValue)
{
	ensure_capacity(_nSize + strValue._nSize);
	
	for (size_t i = 0; i < strValue._nSize; i++)
	{
		_pStrData[_nSize + i] = strValue._pStrData[i];
	}
	_nSize += strValue._nSize;

}

MyString MyString::substr(size_t nPos, int nLen)
{
	if (nLen > _nSize)
	{
		nLen = _nSize - nPos;
	}

	MyString strTemp(&_pStrData[nPos], nLen);
	return strTemp;
}

size_t MyString::find(const MyString& strValue, size_t nPos) const
{
	if (strValue._nSize == 0 || nPos > _nSize || strValue._nSize > _nSize - nPos)
	{
		return -1; 
	}

	for (size_t i = nPos; i <= _nSize - strValue._nSize; ++i)
	{
		size_t j{};
		while ((j < strValue._nSize) && (_pStrData[i + j] == strValue._pStrData[j]))
		{
			++j;
		}
		if (j == strValue._nSize)
		{
			return i; 
		}
	}

	return -1;
}

int MyString::compare(const MyString& strValue) const
{
	return std::strcmp(_pStrData, strValue._pStrData);
}

void MyString::insert(size_t nPos, const MyString& strValue)
{
	if ((nPos > _nSize))
	{
		throw std::out_of_range("越界插入");
	}

	ensure_capacity(_nSize + strValue._nSize);

	for (size_t i = _nSize; i > nPos; --i)
	{
		_pStrData[i + strValue._nSize - 1] = _pStrData[i - 1];
	}

	for (size_t i = 0; i < strValue._nSize; ++i)
	{
		_pStrData[nPos + i] = strValue._pStrData[i];
	}

	_nSize += strValue._nSize;
	_pStrData[_nSize] = '\0'; // 加上字符串结束符
}

void MyString::erase(size_t nPos, size_t nLen)
{
	if (nPos > _nSize)
	{
		throw std::out_of_range("越界访问");
	}

	if (nPos + nLen > _nSize)
	{
		_pStrData[nPos] = '\0';
		_nSize = nPos;
		return;
	}
	else
	{
		for (size_t i = 0; i < _nSize - nPos - nLen; i++)
		{
			_pStrData[nPos + i] = _pStrData[nPos + nLen + i];
		}
		_nSize -= nLen;
		_pStrData[_nSize] = '\0';
	}
	
}

void MyString::replace(size_t nPos, size_t nLen, const MyString& strValue)
{
	if (nPos > _nSize)
	{
		throw std::out_of_range("越界访问");
	}

	if (nPos + nLen > _nSize)
	{
		nLen = _nSize - nPos;
	}

	erase(nPos, nLen);
	insert(nPos, strValue);
}

MyString& MyString::operator+(const MyString& strValue)
{
	append(strValue);
	return *this;
}

MyString& MyString::operator+=(const MyString& strValue)
{
	append(strValue);
	return *this;
}

char& MyString::operator[](size_t nIndex)
{
	if (nIndex >= _nSize)
		throw std::out_of_range("索引越界");
	return _pStrData[nIndex];
}

const char& MyString::operator[](size_t nIndex) const
{
	if (nIndex >= _nSize)
		throw std::out_of_range("索引越界");
	return _pStrData[nIndex];
}

std::ostream& operator<<(std::ostream& os, const MyString& strValue)
{
	os << strValue._pStrData;
	return os;
}

std::istream& operator>>(std::istream& is, MyString& strValue)
{
	char buf[1024];
	is >> buf;
	strValue = MyString(buf);
	return is;
}

MyString::iterator::iterator(pointer pStr)
	: _pStr(pStr)
{
}

MyString::iterator::reference MyString::iterator::operator*() const 
{
	return *_pStr;
}

MyString::iterator::pointer MyString::iterator::operator->() const 
{
	return _pStr; 
}

MyString::iterator& MyString::iterator::operator++() 
{ 
	++_pStr; 
	return *this; 
}

MyString::iterator& MyString::iterator::operator++(int) 
{ 
	iterator tmp = *this; ++_pStr; 
	return tmp; 
}

MyString::iterator& MyString::iterator::operator--() 
{ 
	--_pStr; 
	return *this; 
}

MyString::iterator& MyString::iterator::operator--(int) 
{
	iterator tmp = *this; --_pStr; 
	return tmp;
}

MyString::iterator& MyString::iterator::operator-(difference_type type) const 
{
	return *new iterator(_pStr - type); 
}

MyString::iterator& MyString::iterator::operator+(difference_type type) const 
{
	return *new iterator(_pStr + type); 
}

MyString::iterator::difference_type MyString::iterator::operator-(const iterator& itValue) const 
{
	return _pStr - itValue._pStr; 
}

bool MyString::iterator::operator==(const iterator& itValue) const 
{ 
	return _pStr == itValue._pStr; 
}

bool MyString::iterator::operator!=(const iterator& itValue) const 
{
	return _pStr != itValue._pStr;
}

bool MyString::iterator::operator<=(const iterator& itValue) const 
{ 
	return _pStr <= itValue._pStr; 
}

bool MyString::iterator::operator>=(const iterator& itValue) const 
{ 
	return _pStr >= itValue._pStr; 
}

bool MyString::iterator::operator<(const iterator& itValue) const 
{ 
	return _pStr < itValue._pStr; 
}

bool MyString::iterator::operator>(const iterator& itValue) const 
{ 
	return _pStr > itValue._pStr;
}

MyString::const_iterator::const_iterator(pointer ptr) : _ptr(ptr) 
{
}

MyString::const_iterator::reference MyString::const_iterator::operator*() const 
{
	return *_ptr;
}

MyString::const_iterator::pointer MyString::const_iterator::operator->() const 
{
	return _ptr;
}

MyString::const_iterator& MyString::const_iterator::operator++() 
{
	++_ptr; return *this; 
}

MyString::const_iterator MyString::const_iterator::operator++(int) 
{ 
	const_iterator tmp = *this; ++_ptr; return tmp;
}

MyString::const_iterator& MyString::const_iterator::operator--() 
{
	--_ptr; return *this;
}

MyString::const_iterator MyString::const_iterator::operator--(int) 
{ 
	const_iterator tmp = *this; --_ptr; return tmp; 
}

MyString::const_iterator MyString::const_iterator::operator+(difference_type type) const 
{
	return const_iterator(_ptr + type);
}

MyString::const_iterator MyString::const_iterator::operator-(difference_type type) const 
{ 
	return const_iterator(_ptr - type); 
}

MyString::const_iterator::difference_type MyString::const_iterator::operator-(const const_iterator& itValue) 
{
	return _ptr - itValue._ptr;
}

bool MyString::const_iterator::operator==(const const_iterator& itValue) const 
{
	return _ptr == itValue._ptr;
}

bool MyString::const_iterator::operator!=(const const_iterator& itValue) const
{ 
	return _ptr != itValue._ptr; 
}

bool MyString::const_iterator::operator<(const const_iterator& itValue) const 
{
	return _ptr < itValue._ptr; 
}

bool MyString::const_iterator::operator>(const const_iterator& itValue) const 
{ 
	return _ptr > itValue._ptr; 
}

bool MyString::const_iterator::operator<=(const const_iterator& itValue) const 
{ 
	return _ptr <= itValue._ptr;
}

bool MyString::const_iterator::operator>=(const const_iterator& itValue) const 
{ 
	return _ptr >= itValue._ptr; 
}

MyString::iterator MyString::begin() 
{ 
	return iterator(_pStrData); 
}

MyString::iterator MyString::end() 
{ 
	return iterator(_pStrData + _nSize);
}

MyString::const_iterator MyString::cbegin() const 
{
	return const_iterator(_pStrData);
}

MyString::const_iterator MyString::cend() const 
{ 
	return const_iterator(_pStrData + _nSize); 
}
